/*
 * 	This file is a modification of phylip's drawtree.c. It is also part 
 *  of MVD_GUI.
 *
 *  MVD_GUI is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MVD_GUI is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with MVD_GUI.  If not, see <http://www.gnu.org/licenses/>.
 *  This version copyright 2010 Desmond Schmidt
 */
/* version 3.6. (c) Copyright 1993-2004 by the University of Washington.
   Written by Joseph Felsenstein, Akiko Fuseki, Sean Lamont, Andrew Keeffe,
   Mike Palczewski, Doug Buxton and Dan Fineman.
   Permission is granted to copy and use this program provided no fee is
   charged for it and provided that this copyright notice is not removed. */
#ifndef PHYLIP_H
#define PHYLIP_H
#define MAXNCH 20   /* must be greater than or equal to nmlngth */
#define true 1
#define false 0
/* Approx. 1GB, used to test for memory request errors */
#define TOO_MUCH_MEMORY 1000000000
#define Malloc(x) mymalloc(x)
#define epsilon         0.0001  /* small number used in makenewv */
#define FILE_NAME_LEN 128
#define FONT_NAME_LEN 64
#define nmlngth         10   /* number of characters in species name    */

typedef char naym[MAXNCH];
typedef enum 
{
  	A, C, G, T, O
} 
bases;
typedef enum 
{
  alanine, arginine, asparagine, aspartic, cysteine, 
  glutamine, glutamic, glycine, histidine, isoleucine,
  leucine, lysine, methionine, phenylalanine, proline,
  serine, threonine, tryptophan, tyrosine, valine
} acids;
typedef enum 
{
  ala, arg, asn, asp, cys, gln, glu, gly, his, ileu, leu, lys, met, phe, pro,
  ser1, ser2, thr, trp, tyr, val, del, stop, asx, glx, ser, unk, quest
} aas;
typedef enum { bottom, nonbottom, hslength, tip, iter, length,
	hsnolength, treewt, unittrwt } initops;
typedef double sitelike[(int)T - (int)A + 1];   /* used in dnaml, dnadist */
typedef double psitelike[(int)valine - (int)alanine + 1];
typedef sitelike *ratelike;                    /* used in dnaml ...            */
typedef ratelike *phenotype;    /* phenotype used in dnaml, dnamlk, dnadist */
typedef double *sitelike2;
typedef sitelike2 *phenotype2;              /* phenotype2 used in restml    */
typedef double *phenotype3;                 /* for continuous char programs */
typedef psitelike *pratelike;                    /* used in proml                    */
typedef pratelike *pphenotype;  /* phenotype used in proml                    */ 
typedef int sitearray[3];
typedef sitearray *seqptr;                    /* seqptr used in protpars */
typedef enum { nocollap, tocollap, undefined } collapstates;
typedef int *baseptr;       /* baseptr used in dnapars, dnacomp & dnapenny */
typedef int *baseptr2;      /* baseptr used in dnamove                     */
typedef unsigned char *discbaseptr;         /* discbaseptr used in pars     */
typedef int nucarray[(int)O - (int)A + 1];
typedef enum {
  zero = 0, one, two, three, four, five, six, seven
} discbases;
typedef int discnucarray[(int)seven - (int)zero + 1];
typedef int *steptr;
typedef double *vector;                     /* used in distance programs    */
typedef int *bitptr;
typedef unsigned char boolean;
typedef enum {fixed, radial, along, middle} labelorient;
typedef int longer[6];
typedef double **transmatrix;
typedef transmatrix *transptr;                /* transptr used in restml */
typedef struct node 
{
  struct node *next, *back;
  char nayme[MAXNCH];
  int naymlength, tipsabove, index;
  double times_in_tree;            /* Previously known as cons_index */
  double xcoord, ycoord;
  int int_xcoord, int_ycoord;         /* for use in cons.               */
  double oldlen, length, r, theta, oldtheta, width, depth,
         tipdist, lefttheta, righttheta;
  int *nodeset;                   /* used by accumulate      -plc   */
  int ymin, ymax;                       /* used by printree        -plc   */
  boolean haslength;               /* haslength used in dnamlk             */
  boolean iter;                    /* iter used in dnaml, fitch & restml   */
  boolean initialized;             /* initialized used in dnamlk & restml  */
  int branchnum;                  /* branchnum used in restml             */
  phenotype x;                     /* x used in dnaml, dnamlk, dnadist     */
  phenotype2 x2;                   /* x2 used in restml                    */
  phenotype3 view;                 /* contml etc                           */
  pphenotype protx;                /* protx used in proml */ 
  aas *seq;                  /* the sequence used in protpars              */
  seqptr siteset;            /* temporary storage for aa's used in protpars*/
  double v, deltav, ssq;       /* ssq used only in contrast                */
  double bigv;                 /* bigv used in contml                      */
  double tyme, oldtyme;        /* used in dnamlk                           */
  double t;                    /* time in kitsch                           */
  boolean sametime;            /* bookkeeps scrunched nodes in kitsch      */
  double weight;               /* weight of node used by scrunch in kitsch */
  boolean processed;           /* used by evaluate in kitsch               */
  boolean deleted;        /* true if node is deleted (retree)              */
  boolean hasname;        /* true if tip has a name (retree)               */
  double beyond;          /* distance beyond this node to most distant tip */
                            /* (retree) */
  boolean deadend;          /* true if no undeleted nodes beyond this node */
                            /* (retree) */
  boolean onebranch;        /* true if there is one undeleted node beyond  */
                            /* this node (retree)                          */
  struct node *onebranchnode;
                            /* if there is, a pointer to that node (retree)*/
  double onebranchlength;   /* if there is, the distance from here to there*/
                                /* (retree)                                */
  boolean onebranchhaslength;   /* true if there is a valid combined length*/
                                 /* from here to there (retree)            */
  collapstates collapse;         /* used in dnapars & dnacomp              */
  boolean tip;
  boolean bottom;                /* used in dnapars & dnacomp, disc char   */
  boolean visited;               /* used in dnapars & dnacomp  disc char   */
  baseptr base;                  /* the sequence in dnapars/comp/penny     */
  discbaseptr discbase;          /* the sequence in pars                   */
  baseptr2 base2;                /* the sequence in dnamove                */
  baseptr oldbase;               /* record previous sequence               */
  discbaseptr olddiscbase;       /* record previous sequence               */
  int numdesc;                  /* number of immediate descendants        */
  nucarray *numnuc;              /* bookkeeps number of nucleotides        */
  discnucarray *discnumnuc;      /* bookkeeps number of nucleotides        */
  steptr numsteps;               /* bookkeeps steps                        */
  steptr oldnumsteps;            /* record previous steps                  */
  double sumsteps;               /* bookkeeps sum of steps                 */
  nucarray cumlengths;           /* bookkeeps cummulative minimum lengths  */
  discnucarray disccumlengths;   /* bookkeeps cummulative minimum lengths  */
  nucarray numreconst;           /* bookkeeps number of  reconstructions   */
  discnucarray discnumreconst;   /* bookkeeps number of  reconstructions   */
  vector d, w;                   /* for distance matrix programs           */
  double dist;                   /* dist used in fitch                     */
  bitptr stateone, statezero;    /* discrete char programs                 */
  int maxpos;                   /* maxpos used in Clique                  */
  char state;                    /* state used in Dnamove, Dolmove & Move  */
  double* underflows;            /* used to record underflow               */
} node;
/*** tree structure ***/
typedef node **pointarray;

/** An array of pointers to nodes. Each tip node and ring of nodes has a
 * unique index starting from one. The nodep array contains pointers to each
 * one, starting from 0. In the case of internal nodes, the entries in nodep
 * point to the rootward node in the group. Since the trees are otherwise
 * entirely symmetrical, except at the root, this is the only way to resolve
 * parent, child, and sibling relationships.
 *
 * Indices in range [0, spp) point to tips, while indices [spp, nonodes)
 * point to fork nodes
 */
typedef struct tree 
{
  pointarray nodep;
  /* A pointer to the first node. Typically, root is used when the tree is rooted,
   * and points to an internal node with no back link. */
  node *root;                    
  /* start is used when trees are unrooted. It points to an internal node whose
   * back link typically points to the outgroup leaf. */
  node *start;                    
  /* In maximum likelihood programs, the most recent evaluation is stored here */
  double likelihood;
  /* Branch transition matrices for restml */
  transptr trans;                 /* all transition matrices */
  int *freetrans;                /* an array of indexes of free matrices */
  int transindex;                /* index of last valid entry in freetrans[] */
} tree;
typedef void (*initptr)(node **, node **, node *, int, int,
	int *, int *, initops, pointarray,
	pointarray, char *, char *, char *, int *);
void allocate_nodep( pointarray *nodep, char *treefile, int *precalc_tips );
void processlength( double *valyew, double *divisor, char *ch, 
	boolean *lengthIsNegative, char *treefile, int *i, int *parens );
void setupnode( node *p, int i );
void gnu( node **grbg, node **p );
void treeread (char *treefile, node **root, pointarray treenode,
	boolean *goteof, boolean *first, pointarray nodep, 
	int *nextnode, boolean *haslengths, node **grbg, initptr initnode,
	boolean unifok, int maxnodes );
void memerror();
void odd_malloc( int x );
void *mymalloc( int x );
int countcomma( char *treefile, int *comma );
void getch_str(char *c, int *parens, char *treefile, int *i);
void getch(char *c, int *parens, FILE *treefile);
void scan_eoln( FILE *f );
boolean eoff_str(char *f, int start);
boolean eoln_str(char *f, int start);
boolean eoff(FILE *f);
boolean eoln(FILE *f);
void chuck(node **grbg, node *p);
char gettc(FILE* file);
char gettc_str(char* file,int *i);
void EOF_error();
void addelement(node **p, node *q, char *ch, int *parens, char *treefile,
    int *i, pointarray treenode, boolean *goteof, boolean *first, pointarray nodep,
    int *nextnode, int *ntips, boolean *haslengths, node **grbg,
    initptr initnode, boolean unifok, int maxnodes);
int take_name_from_tree(char *ch, char *str, char *treefile, int *i);
void hookup(node *p, node *q);
void initseed(int *inseed, int *inseed0, longer seed);
double randum(longer seed);
void randumize(longer seed, int *enterorder);
int count_sibs (node *p);
extern int spp;
extern naym *nayme;                     /* names of species */
void readTreeContents( FILE *treeFile, char **treeContents );
void scan_eoln_str( char *f, int *i );
void plottree( node *p, node *q );
void plotlabels( char *fontname );
#endif
